package org.example.proxy.dynamic.bytebuddy;

import net.bytebuddy.ByteBuddy;
import net.bytebuddy.implementation.InvocationHandlerAdapter;
import net.bytebuddy.matcher.ElementMatchers;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;

/**
 * @author Administrator
 */
public class ByteBuddyProxy {

    private final Object bean;

    public ByteBuddyProxy(Object bean) {
        this.bean = bean;
    }

    public Object getProxy() throws Exception {
        return new ByteBuddy().subclass(bean.getClass())
                .method(ElementMatchers.any())
                .intercept(InvocationHandlerAdapter.of(new AopInvocationHandler(bean)))
                .make()
                .load(ByteBuddyProxy.class.getClassLoader())
                .getLoaded()
                .getDeclaredConstructor()
                .newInstance();
    }

    public static class AopInvocationHandler implements InvocationHandler {

        private final Object bean;

        public AopInvocationHandler(Object bean) {
            this.bean = bean;
        }

        @Override
        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
            String methodName = method.getName();
            if ("wakeup".equals(methodName)) {
                System.out.println("早安~~~");
            } else if ("sleep".equals(methodName)) {
                System.out.println("晚安~~~");
            }
            method.invoke(bean, args);
            return "method.invoke(bean, args)";
        }
    }
}
